package com.zzg.datastructure.stack;

/**
 * @Author zhengzg
 * @Date 2022-08-18
 * @Version v1.0
 */
public class Calculator {
    public static void main(String[] args) {
        /*注意：栈中数组是int类型，除法运算会取整数，结果会出现偏差*/
        String expression = "100-2+3/4";

        // 创建两个栈，符号栈，数字栈
        ArrayStack numStack = new ArrayStack(10);
        ArrayStack operStack = new ArrayStack(10);

        // 定义相关变量
        int index = 0;
        int num1 = 0;
        int num2 = 0;
        int oper = 0;
        int res = 0;
        char ch = ' ';
        // 用于拼接多位数
        StringBuilder keepNum = new StringBuilder();
        while (true){
            // 一次得到expression的每一个字符串
            ch = expression.substring(index,index+1).charAt(0);
            // 判断ch进行相应的处理
            if (operStack.isOper(ch)){
                // 判断当前符号栈是否为null
                if (!operStack.isEmpty()){
                    // 如果当前的操作符的优先级小于或者等于栈中的操作符，就需要从数栈中pop出两个数
                    // 在从符号栈中pop出一个符号，进行运算，将得到结果，入数栈，然后将当前的操作符入符号栈
                    if (operStack.priority(ch) <= operStack.priority(operStack.peek())){
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        oper = operStack.pop();
                        // num2先入栈，按照表达式从左向右运算，将num2，放于前面
                        res = numStack.cal(num2,num1,oper);
                        // 把运算结果入数栈
                        numStack.push(res);
                        // 将当前操作符入符号栈
                        operStack.push(ch);
                    }else {
                        // 优先级大于直接入栈
                        operStack.push(ch);
                    }
                }else {
                    // 符号栈为null 直接入栈
                    operStack.push(ch);
                }
            }else {
                // 数字，入数栈
                // 处理多位数
                keepNum.append(ch);
                // 判断ch是否为最后一位
                if (index == expression.length() - 1){
                    // 直接入栈
                    numStack.push(Integer.parseInt(keepNum.toString()));
                } else {
                    // 判断下一位是否为数字，如果是数字，继续扫描，如果是运算符，直接入栈
                    if (operStack.isOper(expression.substring(index + 1,index + 2).charAt(0))){
                        numStack.push(Integer.parseInt(keepNum.toString()));
                        // 将keepNum清空
                        keepNum.delete(0,keepNum.length());
                    }
                }
            }

            // index+1,并且判断是否扫描到最后
            index++;
            if (index >= expression.length()){
                break;
            }
        }

        // 当表达式扫描完毕，就顺序从数栈和符号栈中pop出相应的数和符号，并运行
        while (!operStack.isEmpty()) {
            // 如果符号栈为null，则计算到最后的结果，数栈中只有一个数字【结果】
            num1 = numStack.pop();
            num2 = numStack.pop();
            oper = operStack.pop();
            res = numStack.cal(num2, num1, oper);
            numStack.push(res);
        }

        // 将数栈的最后数pop出，就是结果
        int res2 = numStack.pop();
        System.out.printf("表达式结果 %s=%d",expression,res2);
    }
}
